#include "arch/loongarch.h"
#include "arch/ls7a.h"
#include "lib/stdout.h"

#pragma GCC diagnostic ignored "-Warray-bounds"

// 初始化设置 i8042 芯片以实现键鼠控制 
void i8042_init(void)
{
	unsigned char data;
	
	/* disable device */
	*(volatile unsigned char*)(LS7A_I8042_COMMAND) = 0xAD;
	*(volatile unsigned char*)(LS7A_I8042_COMMAND) = 0xA7;
	/* flush */
	data = *(volatile unsigned char*)(LS7A_I8042_DATA);
	/* self test */
	*(volatile unsigned char*)(LS7A_I8042_COMMAND) = 0xAA;
	data = *(volatile unsigned char*)(LS7A_I8042_DATA);
	pr_info(i8042_init, "keyboard reponse %x", data);
	
	/* set config byte, enable device and interrupt*/
	*(volatile unsigned char*)(LS7A_I8042_COMMAND) = 0x20;
	data = *(volatile unsigned char*)(LS7A_I8042_DATA);
	*(volatile unsigned char*)(LS7A_I8042_COMMAND) = 0x60;
	*(volatile unsigned char*)(LS7A_I8042_DATA) = 0x07;
	
	/* test */
	*(volatile unsigned char*)(LS7A_I8042_COMMAND) = 0xAB;
	data = *(volatile unsigned char*)(LS7A_I8042_DATA);
	pr_info(i8042_init, "test result %x", data);
	
	/* enable first port */
	*(volatile unsigned char*)(LS7A_I8042_COMMAND) = 0xAE;
	
	/* reset device */
	*(volatile unsigned char*)(LS7A_I8042_DATA) = 0xFF;
	data = *(volatile unsigned char*)(LS7A_I8042_DATA);
	pr_info(i8042_init, "reset result %x", data);
}

// 读 I8042 状态位
int kbd_has_data(void)
{
    unsigned char status = *(volatile unsigned char*)(LS7A_I8042_STATUS); 
    return (status & 0x1U);
}

// 读 I8042 数据口
unsigned char kbd_read_byte(void)
{
    return *(volatile unsigned char*)(LS7A_I8042_DATA);
}

void kbd_clear_buffer(void)
{
	// 定期清空键盘缓冲区，有助于提高键盘响应稳定性
	while (kbd_has_data())
	{
		kbd_read_byte();
	}
}